package se.webbzon.boltzmann.effect;

import java.awt.Color;

import se.webbzon.boltzmann.configuration.Graphics;
import se.webbzon.oschi01.resourceset.ResourceSet;
import se.webbzon.oschi01.textureset.Texture3D;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticObject;
import se.webbzon.oschi01.worldobject.appearance.SimpleAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.XZPlaneAppearance3D;

public class Shadow2DEffect extends WorldStaticObject implements Effect {
	
	// Shadow effect properties
	public static final int	AUTO_ALIGN			= (1<<0);
	public static final int AUTO_RESIZE			= (1<<1);
	public static final int	STEP_ALIGN			= (1<<2);
	public static final int	STEP_RESIZE			= (1<<3);
	
	// The parent of this shadow effect
	private final WorldStaticObject parent;
	
	// Whatever this shadow effect should auto align to its parent upon creation
	private final int properties;
	
	/*============================================================
	Constructors
	============================================================*/

	public Shadow2DEffect(WorldStaticObject parent, ResourceSet<Texture3D> textureSet) {
		this(parent,textureSet,AUTO_ALIGN + AUTO_RESIZE + STEP_ALIGN + STEP_RESIZE);
	}
	
	public Shadow2DEffect(WorldStaticObject parent, ResourceSet<Texture3D> textureSet, int properties) {
		super(WorldObject.onStep, createAppearance(textureSet));
		this.parent = parent;
		this.properties = properties;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the parent of this shadow effect. **/
	public WorldStaticObject getParent() {
		return parent;
	}
	
	@Override public void onStep(WorldArea world) {
		if (isSet(properties,STEP_ALIGN))
			setPosition(parent.getX(),getY(),parent.getZ());
		if (isSet(properties,STEP_RESIZE))
			setSize(parent.getWidth(),1,parent.getDepth());
	}
	
	@Override public void launch(WorldArea world) {
		if (Graphics.instance().hasShadows()) {
			if (isSet(properties,AUTO_ALIGN))
				setPosition(parent.getX(),
							parent.getY() - parent.getHeight()/2,
							parent.getZ());
			if (isSet(properties,AUTO_RESIZE))
				setSize(parent.getWidth(),1,parent.getDepth());
			world.createInstance(this);
		}
	}
	
	@Override public void terminate(WorldArea world) {
		if (getWorld() != null)
			world.destroyInstance(this);
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Returns true if the given property is set in the given properties. **/
	private static final boolean isSet(int properties, int property) {
		return ((properties & property) == property);
	}
	
	/** Creates the shadow appearance. **/
	private static SimpleAppearance3D createAppearance(ResourceSet<Texture3D> textureSet) {
		SimpleAppearance3D appearance = 
				new XZPlaneAppearance3D(1,
										SimpleAppearance3D.TRANSPARENCY +
										SimpleAppearance3D.LAYERS,false);
		
		appearance.setColor(Color.black);
		appearance.setTransparency(0.5f);
		if (textureSet != null)
			appearance.setTextureSet(textureSet);
		appearance.setLayer(0, 5, 0);
		
		return appearance;
	}

}
